#ifndef SCALAR_H
#define SCALAR_H
#include <stdbool.h>

struct Scalar;
typedef struct Scalar *ScalarPtr;

ScalarPtr NewScalar(double v, bool requires_grad);
void FreeScalar(ScalarPtr *ptr);

void FreeGraph(ScalarPtr *ptr);

/**
 * @brief p1 + p2
 */
ScalarPtr Add(ScalarPtr p1, ScalarPtr p2);
ScalarPtr Sub(ScalarPtr p1, ScalarPtr p2);
ScalarPtr Mul(ScalarPtr p1, ScalarPtr p2);
ScalarPtr Div(ScalarPtr p1, ScalarPtr p2);
/**
 * @brief 计算a的b次幂
 */
ScalarPtr Pow(ScalarPtr p1, ScalarPtr p2);
/**
 * @brief 计算log_a(b)
 */
ScalarPtr Log(ScalarPtr p1, ScalarPtr p2);

ScalarPtr Ln(ScalarPtr p);

ScalarPtr Exp(ScalarPtr p);

ScalarPtr Sin(ScalarPtr p);
ScalarPtr Cos(ScalarPtr p);
ScalarPtr Tan(ScalarPtr p);

void Backward(ScalarPtr p);
bool GT(ScalarPtr, double);
double Scalar2Double(ScalarPtr p);

#endif
